using System;
using NUnit.Framework;
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Engine;
using System.Collections;

namespace NHibernate.Test.Playground
{
    public class WorkingWithPersisters : SimpleDynamicProperties
    {
        private AbstractEntityPersister _persister;
        [Test]
        public void get_fragments()
        {
            Output("FromJoinFragment", _persister.FromJoinFragment("alias", true, true));
            Output("FromTableFragment", _persister.FromTableFragment("alias"));
            Output("OneToManyFilterFragment", _persister.OneToManyFilterFragment("alias"));
            Output("PropertySelectFragment", _persister.PropertySelectFragment("name", "suffix", true));
            Output("WhereJoinFragment", _persister.WhereJoinFragment("alias", true, true));
            Output("SelectFragment", _persister.SelectFragment("alias", "suffix"));
        }
        [Test]
        public void get_alias()
        {
            Output("GenerateFilterConditionAlias", _persister.GenerateFilterConditionAlias("rootAlias"));
            Output("GenerateTableAlias", _persister.GenerateTableAlias("alias", 1));
            Output("GetDiscriminatorAlias", _persister.GetDiscriminatorAlias("suffix"));
            Output("GetIdentifierAliases", _persister.GetIdentifierAliases("suffix"));
            Output("GetPropertyAliases 0", _persister.GetPropertyAliases("suffix", 0));
            Output("GetPropertyAliases 1", _persister.GetPropertyAliases("suffix", 1));
            Output("GetRootTableAlias", _persister.GetRootTableAlias("drivingAlias"));
            Output("GetSubclassPropertyColumnAliases", _persister.GetSubclassPropertyColumnAliases("propertyName", "suffix"));
            Output("IdentifierAliases", _persister.IdentifierAliases);
        }
        [Test]
        public void Test()
        {
            var fred = new Customer() { FirstName = "Fred" };
            fred.DynamicProperties.Add("LastName", "Flintstone");
            var barney = new Customer() { FirstName = "Barney" };
            barney.DynamicProperties.Add("LastName", "Rubble");

            var alias = "alias";
            var suffix = "suffix";
            var sql = new SqlString("SELECT ", _persister.SelectFragment(alias, suffix), " FROM ", _persister.FromTableFragment(alias));

            var matrixSuffixedProperties = new string[_persister.PropertyTypes.Length][];
            for (int i = 0; i < _persister.PropertyTypes.Length; i++)
                matrixSuffixedProperties[i] = _persister.GetPropertyAliases("suffix", i);

            using (var s = OpenSession())
            using(var tx = s.BeginTransaction())
            {
                try
                {
                    s.Save(fred);
                    s.Save(barney);
                    s.Flush();
                    s.Evict(fred);
                    s.Evict(barney);
                    var cmd = s.Connection.CreateCommand();
                    cmd.CommandText = sql.ToString();
                    Output(cmd.CommandText);
                    var reader = cmd.ExecuteReader();
                    while (reader.Read())
                    {
                        Output(reader.GetGuid(0));
                        Customer newCustomer = new Customer();
                        var ret = _persister.Hydrate(reader, reader.GetGuid(0), newCustomer, _persister, matrixSuffixedProperties, true, s as ISessionImplementor);
                        foreach (var val in ret)
                            if (val is object[])
                                foreach (var innerVal in (val as object[]))
                                    Output("\t\t" + innerVal.ToString());
                            else
                                Output("\t"+val.ToString());
                    }
                }
                finally
                {
                    tx.Rollback();
                }
            }
        }
        void Output(string persisterMethod, SqlString sql)
        {
            Output(persisterMethod, sql.ToString());
        }
        void Output(string persisterMethod, string[] results)
        {
            Output(persisterMethod, results == null ? "" : String.Join(", ", results));
        }
        void Output(string persisterMethod, string result)
        {
            Output(String.Format("persister.{0}: '{1}'", persisterMethod, result));
        }
        protected override void OnSetUp()
        {
            base.OnSetUp();
            _persister = (AbstractEntityPersister)sessions.GetEntityPersister(typeof(Customer).FullName);
            Output("-----------------");
        }
    }
}
